﻿Option Strict On
Imports Microsoft.WindowsAPICodePack.Taskbar

''' <summary>
''' Moves, deletes or recycles files and displays a dialog indicating operation progress.
''' </summary>
Public Class FileRecycler

    Private Const INT_PROGRESS_STEP As Integer = 10
    Private Const OVERWRITE_ON_MOVE = True

    Private iFileCount As Integer
    Private oFilesToDelete As ArrayList

    Public Enum OperationMode As Short
        MoveToRecycleBin = 1
        DeletePermanently = 2
        MoveToPath = 3
    End Enum

    '---TO DO---
    '   *   exception handling - consider ways in which errors may occur
    '   *   fix always on top/fixed position
    '-----------

    ''' <summary>
    ''' Creates new FileRecycler object.
    ''' </summary>
    ''' <param name="files">An instance of a FileList object containing items that are flagged as both checked and displayed</param>
    ''' <remarks>Need to further consider behaviour if no checked/displayed objects are int the FileList</remarks>
    Public Sub New(ByRef files As FileList)

        InitializeComponent()   ' this call is required by the designer

        iFileCount = files.FileCount(FileList.ItemParamaters.CheckedAndDisplayed) 'count all items flagged as checked and displayed
        oFilesToDelete = New ArrayList

        prgRecycler.Maximum = iFileCount * INT_PROGRESS_STEP    'set paramaters for form status bar display
        prgRecycler.Step = INT_PROGRESS_STEP

        For i As Integer = 0 To files.FileCount - 1
            If (files.Parameters(i) And FileList.ItemParamaters.CheckedAndDisplayed) = FileList.ItemParamaters.CheckedAndDisplayed Then oFilesToDelete.Add(files.ListItemPath(i) & My.Resources.CharPathDelimiter & files.ListItemFilename(i)) 'add filename and path of each item flagged as checked and displayed to an arraylist
        Next

        oFilesToDelete.TrimToSize()   'trim arraylist to actual number of elements to reduce memory overhead

    End Sub

    ''' <summary>
    ''' Initiates a move, recycle or delete operation on files held by the FileRecycler.
    ''' </summary>
    ''' <param name="params">A FileReycler.OperationMode option to specify the operation mode.</param>
    ''' <param name="path">Path to be specified if FileRecycler.MoveToPath operation mode is used.</param>
    ''' <returns>True if operation successful, otherwise false.</returns>
    Public Function PerformFileOperation(ByVal params As OperationMode,
                                         Optional ByVal path As String = vbNullString) As Boolean

        Dim oRecycleOption As FileIO.RecycleOption
        Dim sStatusText As String
        Dim sSuccessText As String
        Dim sDialogConfirmationText As String

        Select Case params
            Case OperationMode.MoveToRecycleBin     'set paramaters and strings for user display for recycling files
                oRecycleOption = FileIO.RecycleOption.SendToRecycleBin
                sStatusText = My.Resources.StatusTextRecycling
                sSuccessText = My.Resources.OutcomeSuccessRecycle
                sDialogConfirmationText = String.Format(My.Resources.PromptConfirm, My.Resources.PromptActionMove, iFileCount, IsPlural, My.Resources.PromptDestinationRecycle)

            Case OperationMode.DeletePermanently    'set paramaters and strings for user display for deletion files
                oRecycleOption = FileIO.RecycleOption.DeletePermanently
                sStatusText = My.Resources.StatusTextDeleting
                sSuccessText = My.Resources.OutcomeSuccessDelete
                sDialogConfirmationText = String.Format(My.Resources.PromptConfirm, My.Resources.PromptActionDelete, iFileCount, IsPlural, String.Empty)

            Case OperationMode.MoveToPath       'set paramaters and strings for user display for moving files
                If Not DirectoryExists(path) Then Return False 'invalid destination path specified
                sStatusText = My.Resources.StatusTextMoving
                sSuccessText = String.Format(My.Resources.OutcomeSuccessMove, path)
                sDialogConfirmationText = String.Format(My.Resources.PromptConfirm, My.Resources.PromptActionMove, iFileCount, IsPlural, String.Format(My.Resources.PromptDestinationPath, path))
            Case Else
                Return False    'invalid paramaters supplied
        End Select

        If DisplayConfirmation(sDialogConfirmationText) Then   'prompt for deletion confirmation
            Dim sCurrentFile As String

            Me.Text = String.Format(My.Resources.DialogTitleRecycler, sStatusText, iFileCount)
            Me.Show()

            For i As Integer = 0 To iFileCount - 1
                sCurrentFile = oFilesToDelete.Item(i).ToString
                lblStatus.Text = String.Format(My.Resources.FormLabelRecyclerStatus, sStatusText, i + 1, iFileCount)
                lblCurrentFile.Text = sCurrentFile
                If params = OperationMode.MoveToPath Then
                    My.Computer.FileSystem.MoveFile(sCurrentFile, My.Computer.FileSystem.CombinePath(path, My.Computer.FileSystem.GetName(sCurrentFile)), FileIO.UIOption.OnlyErrorDialogs)  'move each file
                Else
                    My.Computer.FileSystem.DeleteFile(sCurrentFile, FileIO.UIOption.OnlyErrorDialogs, oRecycleOption)   'delete/recycle each file
                End If

                TaskbarManager.Instance.SetProgressValue(i, iFileCount - 1) 'increment the taskbar progress display
                prgRecycler.PerformStep()   'increment the form progress display
                Refresh()   'ensure form labels are updated
            Next

            MessageBox.Show(String.Format(My.Resources.OutcomeSuccessDialog, iFileCount, sSuccessText), My.Resources.DialogTitleInformation, MessageBoxButtons.OK, MessageBoxIcon.Information)
            Return True
        Else    'user cancelled at confirmation prompt
            MessageBox.Show(My.Resources.OutcomeNothingDialog, My.Resources.DialogTitleInformation, MessageBoxButtons.OK, MessageBoxIcon.Information)
            Return False
        End If

    End Function

    ''' <summary>
    ''' Displays a confirmation dialog to the user.
    ''' </summary>
    ''' <param name="textToDisplay">The text to be displayed by the dialog.</param>
    ''' <returns>True if OK selected, otherwise false.</returns>
    Private Function DisplayConfirmation(ByVal textToDisplay As String) As Boolean

        If MessageBox.Show(textToDisplay, My.Resources.DialogTitleConfirmation, MessageBoxButtons.OKCancel, MessageBoxIcon.Question) = DialogResult.OK Then Return True Else Return False

    End Function

    ''' <summary>
    ''' Returns string to append to 'item' string to indicate plurality based on file count.
    ''' </summary>
    ''' <returns>String to append to 'item' to inducate plurality</returns>
    ''' <remarks></remarks>
    Private Function IsPlural() As String

        If iFileCount > 1 Then Return My.Resources.CharPlural Else Return String.Empty 'return string to append to item to indicate plurality

    End Function

End Class